package cn.wind.xboot.module.web.controller.sys;

import cn.wind.xboot.core.annotation.RestJsonController;
import cn.wind.xboot.core.res.ApiResult;
import cn.wind.xboot.core.utils.BlankUtil;
import cn.wind.xboot.logic.sys.entity.SysPermission;
import cn.wind.xboot.logic.sys.entity.SysPrivilege;
import cn.wind.xboot.logic.sys.entity.SysRole;
import cn.wind.xboot.logic.sys.entity.SysUserRole;
import cn.wind.klog.annotation.Log;
import cn.wind.klog.annotation.LogAround;
import cn.wind.xboot.framework.domain.PageVo;
import cn.wind.xboot.framework.web.controller.BaseController;
import cn.wind.xboot.module.web.handler.MyLogHandler;
import cn.wind.xboot.module.web.vo.sys.SysRoleVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>Title: RoleController</p>
 * <p>Description: TODO</p>
 *
 * @author xukk
 * @version 1.0
 * @date 2018/6/25
 */
@Slf4j
@RestJsonController
@Api(value = "role",tags = "角色管理接口")
@RequestMapping("role")
public class RoleController extends BaseController<SysRole, Long> {

    @Override
    public IService getService() {
        return sysRoleService;
    }

    @PreAuthorize("hasRole('system:role:view')")
    @GetMapping
    @ApiOperation(value = "获取全部角色")
    public ApiResult roleGetAll(PageVo pageVo) {
        IPage<SysRole> page = sysRoleService.page(pageVo.init(),new QueryWrapper<SysRole>().lambda().orderByDesc(SysRole::getCreateTime));
        return ApiResult.Custom().success().add(page);
    }
    @PreAuthorize("hasRole('system:role:add')")
    @PostMapping
    @ApiOperation(value = "添加角色")
    public ApiResult save(SysRoleVo entity) throws Exception {
        return super.save(beanMapper.map(entity,SysRole.class));
    }

    @PreAuthorize("hasRole('system:role:view')")
    @GetMapping(value = "list")
    @ApiOperation(value = "分页获取角色")
    public ApiResult get(PageVo pageVo) {
        QueryWrapper<SysRole>  qw=new QueryWrapper<>();
        if(BlankUtil.isNotBlank(pageVo.getSearchKey())){
            qw.lambda().like(SysRole::getName,pageVo.getSearchKey())
                    .or().like(SysRole::getTitle,pageVo.getSearchKey());
        }
        IPage<SysRole> list = sysRoleService.page(pageVo.init(),qw);
        for (SysRole role : list.getRecords()) {
            List<SysPermission> permissions = sysPermissionService.findByRoleId(role.getId());
            role.setPermissions(permissions);
        }
        return ApiResult.Custom().success().add(list);
    }

    @PreAuthorize("hasRole('system:role:delete')")
    @Override
    @DeleteMapping
    @ApiOperation(value = "批量通过ids删除")
    public ApiResult delete(@RequestParam Long[] ids) {
        for (Long id : ids) {
            List<SysUserRole> list = sysUserRoleService.findByRoleId(id);
            if (list != null && list.size() > 0) {
                return ApiResult.Custom().failure("删除失败，包含正被使用中的角色");
            }
        }
        sysRoleService.removeByIds(Arrays.stream(ids).collect(Collectors.toList()));
        return ApiResult.Custom().success("批量通过id删除数据成功");
    }

    @PreAuthorize("hasRole('system:role:edit')")
    @PutMapping
    @ApiOperation(value = "更新数据")
    @LogAround
    @Log(value = "更新用户角色",fallback = MyLogHandler.class)
    public ApiResult edit(@ModelAttribute SysRoleVo roleVo) {
        if (sysRoleService.getById(roleVo.getId()) == null) {
            return ApiResult.Custom().failure("无法找到该资源");
        }
        SysRole sysRole = beanMapper.map(roleVo, SysRole.class);
        sysRoleService.update(sysRole, new UpdateWrapper<SysRole>().lambda().eq(SysRole::getId, roleVo.getId()));
        //手动批量删除缓存
        Set<String> keysUser = redisTemplate.keys("user:" + "*");
        redisTemplate.delete(keysUser);
        Set<String> keysUserRole = redisTemplate.keys("userRole:" + "*");
        redisTemplate.delete(keysUserRole);
        return ApiResult.Custom().success();
    }

    @PreAuthorize("hasRole('system:role:editPerm')")
    @PostMapping(value = "/perm/{roleId}")
    @ApiOperation(value = "编辑角色分配权限")
    public ApiResult editRolePerm(@PathVariable Long roleId,
                                  @RequestParam(required = false) Long[] permIds) {

        //删除其关联权限
        sysPrivilegeService.deleteByRoleId(roleId);
        //分配新权限
        for (Long permId : permIds) {
            SysPrivilege rolePermission = new SysPrivilege();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permId);
            sysPrivilegeService.save(rolePermission);
        }
        //手动批量删除缓存
        Set<String> keysUser = redisTemplate.keys("user:" + "*");
        redisTemplate.delete(keysUser);
        Set<String> keysUserRole = redisTemplate.keys("userRole:" + "*");
        redisTemplate.delete(keysUserRole);
        Set<String> keysUserPerm = redisTemplate.keys("userPermission:" + "*");
        redisTemplate.delete(keysUserPerm);
        Set<String> keysUserMenu = redisTemplate.keys("permission::userMenuList:*");
        redisTemplate.delete(keysUserMenu);
        return ApiResult.Custom().success();
    }
}
